package com.aplink.generic.widgets;

import java.text.DecimalFormat;
import java.text.ParseException;

import android.os.Bundle;
import android.text.InputFilter;
import android.text.TextUtils;
import android.text.method.DigitsKeyListener;
import android.text.method.PasswordTransformationMethod;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnFocusChangeListener;
import android.widget.EditText;

import com.aplink.generic.GenericFragment;
import com.aplink.generic.constant.type.EditTextType;
import com.aplink.generic.dictionary.GenericDictionary;
import com.aplink.generic.interfaces.OnGetObjProInfo;
import com.aplink.generic.pojo.GenericAttribute;
import com.aplink.generic.pojo.GenericObject;
import com.aplink.generic.pojo.ObjPropInfo;
import com.aplink.generic.pojo.controlspec.ControlSpec;
import com.aplink.generic.pojo.controlspec.EditTextSpec;
import com.aplink.generic.pojo.controlspec.textview.DisplayStyle;
import com.aplink.generic.util.DateTimeUtils;
import com.aplink.generic.util.Language;
import com.aplink.generic.util.LogUtil;
import com.aplink.generic.util.ResourcesHelper;
import com.aplink.generic.util.objectrule.ObjectBaseRule;
import com.aplink.generic.widgets.custom.FloatingEditText;

public class ApLinkFloatingEditText extends ApLinkBaseView implements
		OnFocusChangeListener {
	private transient final FloatingEditText mEditText;
	private final EditTextSpec mEditTextSpec;
	private OnGetObjProInfo mGetObjProInfo;
	private EditTextType mInputType;

	public ApLinkFloatingEditText(final GenericFragment dataEntryActivity,
			final ControlSpec controlSpec, final View view, Bundle bundle) {
		super(dataEntryActivity, controlSpec, view, bundle);
		this.mEditText = (FloatingEditText) view;
		this.mEditTextSpec = (EditTextSpec) controlSpec;
	}

	@Override
	public void clear() {
		this.mEditText.setText(null);
		this.mEditText.setTag(null);
	}

	private void formatText(final boolean hasFocus, final EditText editText) {
		if (editText.getText().length() == 0) {
			return;
		}
		if (hasFocus) {
			if (editText.getText().length() > 0) {
				if (mEditTextSpec.getDisplayStyle().equals(DisplayStyle.MONEY)) {
					if (!TextUtils.isEmpty(mEditTextSpec.getDisplayFormat())) {
						final DecimalFormat dec = new DecimalFormat(
								mEditTextSpec.getDisplayFormat());
						try {
							final String value = dec.parse(
									editText.getText().toString()).toString();
							editText.setText(value);
							mEditText.setTag(value);
						} catch (final ParseException e) {
							e.printStackTrace();
						}
					}
				}
			}
		} else {
			if (mEditTextSpec.getDisplayStyle().equals(DisplayStyle.MONEY)) {
				if (!TextUtils.isEmpty(mEditTextSpec.getDisplayFormat())) {
					final Double number = Double.valueOf(editText.getText()
							.toString());
					final DecimalFormat dec = new DecimalFormat(
							mEditTextSpec.getDisplayFormat());
					editText.setText(dec.format(number));
					mEditText.setTag(number);
				}
			}
		}
	}

	@Override
	public GenericAttribute getAttribute() {
		final String name = this.mEditTextSpec.getMappingName();
		final String dataObj = this.mEditTextSpec.getDataObject();
		ObjPropInfo objPropInfo = null;
		if (name == null) {
			objPropInfo = this.mGetObjProInfo.getObjProInfoTemp();
		} else {
			objPropInfo = getGenericFragment().getContentData().get(
					dataObj + "." + name);
		}
		String value = this.mEditText.getText().toString();
		final DisplayStyle displayType = this.mEditTextSpec.getDisplayStyle();
		if (displayType.equals(DisplayStyle.DATETIME)
				|| displayType.equals(DisplayStyle.CURRENT_DATETIME)) {
			try {
				final long miliseconds = DateTimeUtils.parse(value);
				value = String.valueOf(miliseconds / 1000L);
			} catch (final ParseException e) {
				LogUtil.error(e.getMessage(), "Get attribute from EditText",
						getClass());
			}
		} else if (displayType.equals(DisplayStyle.MONEY)) {
			if (!TextUtils.isEmpty(mEditTextSpec.getDisplayFormat())) {
				if (this.mEditText.getTag() != null) {
					value = this.mEditText.getTag().toString();
				} else {
					value = mEditText.getText().toString();
				}
			}
		}
		return GenericAttribute.obtain(value, objPropInfo);
	}

	@Override
	public GenericDictionary<String, GenericAttribute> getListAttributes() {
		return null;
	}

	@Override
	public EditText getView() {
		return this.mEditText.getEditText();
	}

	@Override
	protected void initViewProperties() {
		final boolean isReadOnly = this.mEditTextSpec.isReadOnly();
		if (isReadOnly) {
			this.mEditText.setKeyListener(null);
			this.mEditText.setEnabled(false);
			this.mEditText.setCursorVisible(false);
			this.mEditText.setFocusable(false);
			this.mEditText.setFocusableInTouchMode(false);
		}

		this.mInputType = this.mEditTextSpec.getDataInputType();
		if (this.mInputType != null) {
			this.mEditText.setInputType(this.mInputType.getValue());
		}
		if (mEditTextSpec.isSingleLine()) {
			mEditText.setSingleLine(mEditTextSpec.isSingleLine());
		}
		if (this.mInputType.equals(EditTextType.PASSWORD)) {
			this.mEditText.setTransformationMethod(PasswordTransformationMethod
					.getInstance());
		}
		this.mEditText
				.setFilters(new InputFilter[] { new InputFilter.LengthFilter(
						this.mEditTextSpec.getMaxLength()) });

		if (this.mEditTextSpec.hasBaseRule()) {
			final ObjectBaseRule baseRule = this.mEditTextSpec
					.getObjectBaseRule();
			final boolean isEnable = baseRule.isSatisfiedCondition(
					getPassedObject(), -1);
			this.mEditText.setEnabled(isEnable);
		}

		if (this.mEditTextSpec.getGetObjProInfo() != null) {
			this.mGetObjProInfo = this.mEditTextSpec.getGetObjProInfo();
		}
		if (!TextUtils.isEmpty(mEditText.getHint())) {
			mEditTextSpec.setHint(mEditText.getHint().toString());
			mEditText.setHint(Language.getInstance().get(
					mEditText.getHint().toString()));
		}

		if (!TextUtils.isEmpty(mEditTextSpec.getDigist())) {
			mEditText.setKeyListener(DigitsKeyListener
					.getInstance(mEditTextSpec.getDigist()));
		}

	}

	@Override
	public void languageChanged() {
		if (!TextUtils.isEmpty(mEditTextSpec.getHint())) {
			mEditText.setHint(Language.getInstance().get(
					mEditTextSpec.getHint()));
		}
	}

	@Override
	protected void loadBindingObject() {
		final String key = String.format("%s.%s",
				this.mEditTextSpec.getDataObject(),
				this.mEditTextSpec.getMappingName());
		String content = null;
		if (this.mEditTextSpec.getValue() != null) {
			content = this.mEditTextSpec.getValue();
		} else {
			content = getPassedObject().getValue(key);
		}
		if (TextUtils.isEmpty(content)) {
			this.mEditText.getText().clear();
		} else {
			final DisplayStyle displayStyle = this.mEditTextSpec
					.getDisplayStyle();
			try {
				if (displayStyle.equals(DisplayStyle.DATETIME)
						|| displayStyle.equals(DisplayStyle.CURRENT_DATETIME)) {
					final String longValue = getPassedObject().getValue(key);
					if ((longValue != null) && !longValue.equals("0")) {
						final Double milis = Double.parseDouble(longValue);
						final Long milliseconds = milis.longValue();
						content = DateTimeUtils.getDateTime(milliseconds,
								this.mEditTextSpec.getDisplayFormat());
					} else {
						final long milliseconds = DateTimeUtils
								.getCurrentDateTime(true);
						content = DateTimeUtils.getDateTime(true, milliseconds,
								this.mEditTextSpec.getDisplayFormat());
					}
				} else {
					content = getPassedObject().getValue(key);
				}
			} catch (final NumberFormatException e) {
				LogUtil.error(e.getMessage(), "loadPassedDataValueIntoView",
						getClass());
			} catch (final ParseException e) {
				e.printStackTrace();
			}
			
			if (TextUtils.isEmpty(content)) {
				this.mEditText.getText().clear();
			} else {
				this.mEditText.setText(content);
			}
			
			// if (getPassedContent() != null) {
			// this.mEditText.setText(getPassedContent());
			// } else {
			// if (TextUtils.isEmpty(content)) {
			// this.mEditText.getText().clear();
			// } else {
			// this.mEditText.setText(content);
			// }
			// }
		}
	}

	@Override
	protected void loadDefaultObject() {
		if (this.mEditTextSpec.getDisplayStyle().equals(
				DisplayStyle.CURRENT_DATETIME)) {
			try {
				final long milliseconds = DateTimeUtils.getCurrentDateTime();
				final String content = DateTimeUtils.getDateTime(milliseconds);
				this.mEditText.setText(content);
			} catch (final ParseException e) {
				e.printStackTrace();
			}
		} else {
			final String dataObj = this.mEditTextSpec.getDataObject();
			String content = null;
			final String mappingName = this.mEditTextSpec.getMappingName();
			final DisplayStyle displayStyle = this.mEditTextSpec
					.getDisplayStyle();
			final String fullColumnName = dataObj + "." + mappingName;
			final GenericObject initValue = getGenericFragment()
					.getInitValues();
			if (dataObj != "") {
				try {
					if (displayStyle.equals(DisplayStyle.DATETIME)
							|| displayStyle
									.equals(DisplayStyle.CURRENT_DATETIME)) {
						final String longValue = getPassedObject().getValue(
								fullColumnName);
						if ((longValue != null) && !longValue.equals("0")) {
							final Double milis = Double.parseDouble(longValue);
							final Long milliseconds = milis.longValue();
							content = DateTimeUtils.getDateTime(milliseconds,
									this.mEditTextSpec.getDisplayFormat());
						} else {
							final long milliseconds = DateTimeUtils
									.getCurrentDateTime(true);
							content = DateTimeUtils.getDateTime(true,
									milliseconds,
									this.mEditTextSpec.getDisplayFormat());
						}
					} else if ((initValue != null)
							&& initValue.containsKey(fullColumnName)) {
						content = initValue.get(fullColumnName).getValue();
					} else {
						content = getPassedObject().getValue(fullColumnName);
					}
				} catch (final NumberFormatException e) {
					LogUtil.error(e.getMessage(),
							"loadPassedDataValueIntoView", getClass());
				} catch (final ParseException e) {
					e.printStackTrace();
				}
			}
			if (!TextUtils.isEmpty(content)) {
				this.mEditText.setText(content);
			}
		}
	}

	@Override
	public void onFocusChange(final View v, final boolean hasFocus) {
		final EditText editText = (EditText) v;
		formatText(hasFocus, editText);
	}

	@Override
	protected void setEventListener() {
		final boolean isSearch = this.mEditTextSpec.isSearch();
		if ((isSearch == true)
				&& (this.mEditTextSpec.getSearchControl() != null)) {
			final int idSearchControl = ResourcesHelper
					.getViewIdByName(this.mEditTextSpec.getSearchControl());
			if (idSearchControl == ResourcesHelper.RESOURCE_NOT_FOUND) {
				return;
			}
		}
		mEditText.setOnFocusChangeListener(this);
	}

	@Override
	public void setObjPropInfoTemp(final OnGetObjProInfo getObjProInfo) {
		this.mGetObjProInfo = getObjProInfo;
	}

	@Override
	public void setOnClickListener(final OnClickListener onClickListener) {
		throw new UnsupportedOperationException(this.getClass().getSimpleName()
				+ " is not support this method");
	}
}
